package main

import (
	"fmt"
	"go.demo/ccmouse/retriever/mock"
	"go.demo/ccmouse/retriever/real"
	"time"
)

//实现了接口的所有方法就算是实现了这个接口
//接口类型变量可以接收struct,也可以接收struct的指针
//接口是值类型,不要使用接口的指针
//interface{}表示任何类型
type IRetriever interface {
	Get(url string) string
}

type IPoster interface {
	Post(url string, form map[string]string) string
}

type IRetrieverPoster interface {
	IRetriever
	IPoster
}

func main() {
	var r IRetriever
	retriever := &mock.Retriever{Contents: "this is a fake imooc.com"}
	r = retriever
	//fmt.Println(download(r))
	inspect(r)
	fmt.Println("----接口类型变量接收struct指针类型")
	r = &real.Retriever{UserAgent: "Mozilla/5.0",
		TimeOut: time.Minute}
	//fmt.Println(download(r))
	inspect(r)
	fmt.Println("----类型判定")
	if retriever, ok := r.(*real.Retriever); ok {
		//if retriever, ok := r.(mock.Retriever); ok {
		fmt.Println(retriever)
	} else {
		fmt.Println("not a assert type")
	}

	fmt.Println("Try a session")
	fmt.Println(session(retriever))
}
func session(rp IRetrieverPoster) string {
	rp.Get(url)
	rp.Post(url, map[string]string{
		"contents": "another faked imooc.com",
	})

	return rp.Get(url)
}

const url = "http://www.imooc.com"

func post(poster IPoster) {
	poster.Post(url, map[string]string{
		"name":   "ccmouse",
		"course": "gp;amg",
	})
}

func download(r IRetriever) string {
	return r.Get(url)
}

func inspect(r IRetriever) {
	fmt.Println("Inspecting", r)
	fmt.Printf("> %T %v\n", r, r)
	fmt.Print("> type switch:")
	switch v := r.(type) {
	case *mock.Retriever:
		fmt.Println("Contents:", v.Contents)
	case *real.Retriever:
		fmt.Println("UserAgent:", v.UserAgent)
	}
}
